#ifndef __UDP_SERVER_HPP__
#define __UDP_SERVER_HPP__

#include<iostream>
#include<string>
#include<memory>
#include<cstring>
#include<cerrno>
#include<string.h>

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#include"InetAddr.hpp"
#include"Log.hpp"
#include"Common.hpp"

using namespace Log_M;

class Udp_server
{
    private:
    int _sockfd;
    InetAddr _addr;
    bool _isruning;

    public:
    Udp_server(uint16_t port=8080)
    :_sockfd(-1),
    _addr(port),
    _isruning(false)
    {
    }

    void InitServer()
    {
        _sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(_sockfd<0)
        {
            Log(Log_Level::FATAL)<<"socket fail";
            Die(SCOKET_ERR);
        }
        Log(Log_Level::INFO)<<"socket success,sockfd is :";
        cout<<_sockfd;

        int n=bind(_sockfd,_addr.Netaddr(),_addr.NetAddrLen());
        if(n<0)
        {
            Log(Log_Level::FATAL)<<"bind";
            Die(BIND_ERR);
        }
        Log(Log_Level::INFO)<<"bind success";
    }

    void start()
    {
        _isruning=true;
        while(true)
        {
            char inbuffer[1024];
            struct sockaddr_in peer;
            socklen_t len=sizeof(peer);

            ssize_t n= recvfrom(_sockfd,inbuffer,sizeof(inbuffer)-1,0,Change(&peer),&len);
            if(n>0)
            {
                InetAddr client(peer);
                inbuffer[n]=0;

                string client_info=client.Ip()+":"+to_string(client.Port())+"#say"+inbuffer;
                Log(Log_Level::INFO)<<client_info;
                string to="发送的信息是：";
                to+=inbuffer;
                sendto(_sockfd,to.c_str(),to.size(),0,Change(&peer),sizeof(peer));
            }        
        }
        _isruning=false;
    }
    ~Udp_server()
    {
        if(_sockfd>-1)
        {
            close(_sockfd);
        }
    }
};
#endif